/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pe.com.deuda.bd.hibernate;

/**
 *
 * @author Sistemas
 */

import java.util.HashMap;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;


/**
 * Clase de utilidad para conseguir la sesi�n de Hibernate.
 * La sesi�n es �nica por thread.
 * Pueden existir varios ficheros de configuraci�n.
 *
 * @author cbasurtoy
 * @version 1.0
 * @see 08.18.2010
 */
public class HibernateMultiple{

    /** Clave para acceder a la sesi�n por defecto, esta sesi�n se obtiene a partir del fichero de configuraci�n "hibernate.cfg.xml". */
    public static final String BD_DEUDA = "BDLOCAL";

    public static final String FILE_NAME_DEUDA = "hibernate.cfg.xml";

    /** Mapa donde se guardan los SessionFactory para cada uno de los ficheros de configuraci�n. */
    private static final Map<String, SessionFactory> sessionFactorys = new HashMap();

    /** Atributo �nico por threat donde se guardan las sesiones para cada uno de los ficheros de configuraci�n. */
    ////private static final ThreadLocal<Map<String, Session>> sessions = new ThreadLocal<Map<String, Session>>();

    private static final Map<String, Session> sessions  = new HashMap<String, Session>();

    static {
        try {
            // Create the DEFAULT SessionFactory from hibernate.cfg.xml
            SessionFactory sessionFactory = new AnnotationConfiguration().configure(FILE_NAME_DEUDA).buildSessionFactory();
            sessionFactorys.put(BD_DEUDA, sessionFactory);

        } catch (Throwable e) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + e);
            throw new ExceptionInInitializerError(e);
        }

    }

    /**
     * A�ade un nuevo fichero de configuraci�n, creando el SessionFactory correspondiente.
     * Para encontrar el fichero de configuraci�n, este debe encontrarse en el classpath,
     * junto al fichero de configuraci�n por defecto de hibernate "hibernate.cfg.xml".
     *
     * @param fileName nombre del fichero de configuraci�n que se quiere a�adir.
     * @param key clave con la que se har� referencia a esta configuraci�n en las siguientes llamadas.
     * @throws HibernateException si no se puede crear el SessionFactory basado en el fichero que se pasa como
     *             argumento.
     */
    public static void addConfigFile(String fileName, String key) throws HibernateException {
        //new Configuration().configure(fileName).buildSessionFactory();
        //aqui se esta creando session factory por la otra base de datos que se va usar
        SessionFactory sessionFactory = new AnnotationConfiguration().configure(fileName).buildSessionFactory();
        sessionFactorys.put(key, sessionFactory);
    }

    /**
     * Devuelve la sesi�n, para el thread que hace la llamada. Es decir cada thread tiene su propia sesi�n.
     *
     * @param key clave que identifica la sesi�n a la que se quiere acceder.
     * @return sesi�n por defecto, para el thread que hace la llamada.
     * @throws HibernateException
     */
    public static Session currentSession(String key) throws HibernateException {
        ////Map<String, Session> ss = sessions.get();
        System.err.println("sessions:"+sessions);
        Session s = sessions.get(key);

        // Abre una nueva sesi�n si este thread todav�a no tiene ninguna
        if (s == null) {
            s = sessionFactorys.get(key).openSession();
            sessions.put(key, s);
        }
        return s;
    }

    /**
     * Cierra la sesi�n, para el thread que hace la llamada.
     *
     * @param key clave que identifica la sesi�n que se quiere cerrar.
     * @throws HibernateException
     */
    public static void closeSession(String key) throws HibernateException {
        ////Map<String, Session> ss = sessions.get();
        System.err.println("sessions:"+sessions);
        Session s = sessions.get(key);
        System.err.println("session :"+s);
        if (s != null) {
            s.close();
            sessions.put(key, null);
        }
    }

    /**
     * Devuelve la sesi�n por defecto, para el thread que hace la llamada.
     * Es decir cada thread tiene su propia sesi�n.
     *
     * @return sesi�n por defecto, para el thread que hace la llamada.
     * @throws HibernateException
     */
    public static Session currentSession() throws HibernateException {
        return currentSession(BD_DEUDA);
    }

    /**
     * Cierra la sesi�n por defecto, para el thread que hace la llamada.
     *
     * @throws HibernateException
     */
    public static void closeSession() throws HibernateException {
        closeSession(BD_DEUDA);
    }
}
